/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bff.core.action.retrieve;

import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bff.api.exception.BffFrameworkException;
import com.inspur.edp.bff.api.exception.ErrorCodes;
import com.inspur.edp.bff.api.param.retrieve.RetrieveChildResult;
import com.inspur.edp.bff.spi.AbstractFSAction;
import com.inspur.edp.cef.entity.dependenceTemp.Pagination;
import com.inspur.edp.cef.entity.entity.IEntityData;
import com.inspur.edp.cef.entity.entity.IEntityDataCollection;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class RetrieveChildByIndexAction extends AbstractFSAction<RetrieveChildResult> {
    private ArrayList<String> nodeCodes, hierachyIds;
    private Pagination pagination;

    public RetrieveChildByIndexAction(ArrayList<String> nodeCodes, ArrayList<String> hierachyIds, Pagination pagination) {
        this.nodeCodes = nodeCodes;
        this.hierachyIds = hierachyIds;
        this.pagination = pagination;
    }

    @Override
    protected void execute() {
        nodeCodes = coverterNodeCode(nodeCodes);
        if (nodeCodes == null || hierachyIds == null || nodeCodes.size() != hierachyIds.size() || pagination == null)
            throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1010);

        IEntityData entityData = getContext().getBffManager().retrieve(hierachyIds.get(0), new RetrieveParam());//考虑是否加锁
        if (entityData == null)
            throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1011);

        IEntityDataCollection childCollection = entityData.getChilds().get(nodeCodes.get(0));
        for (int i = 1; i < nodeCodes.size(); i++) {
            if (childCollection.tryGet(hierachyIds.get(i)) == null)
                throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1012, hierachyIds.get(i));
            childCollection = childCollection.tryGet(hierachyIds.get(i)).getChilds().get(nodeCodes.get(i));
            if (childCollection == null)
                break;
        }
        if (childCollection != null && childCollection.size() > 0 && pagination.getPageSize() != 0)//超出索引返回最后一页
        {
            Integer rem = childCollection.size() % pagination.getPageSize();
            Integer newIndexTemp = childCollection.size() / pagination.getPageSize();
            Integer index = rem == 0 ? newIndexTemp : newIndexTemp + 1;
            if (pagination.getPageIndex() - index >= 1) {
                pagination.setPageIndex(index);
            }
        }
        for (IEntityData child : childCollection) {
            for (Map.Entry<String, IEntityDataCollection> data : child.getChilds().entrySet()) {
                data.getValue().clear();
            }
        }
        setResult(GetDataByIndex(childCollection, pagination));
    }

    private ArrayList<String> coverterNodeCode(ArrayList<String> nodeCodes) {
        ArrayList<String> codes = new ArrayList<>();
        for (String code : nodeCodes) {
            String voKey = getContext().getVoCode(code);
            codes.add(voKey);
        }
        return codes;
    }

    private RetrieveChildResult GetDataByIndex(IEntityDataCollection childData, Pagination pagination) {
        int pageIndex = pagination.getPageIndex();
        if (pageIndex >= 1) {
            int pageSize = pagination.getPageSize();

            int otherCount = childData.size() - (pageIndex - 1) * pageSize;
            int pageCount = pageIndex * pageSize;
            if (otherCount < pageSize)
                pageCount = childData.size();

            Pagination pg = new Pagination();
            pg.setPageSize(pageSize);
            pg.setTotalCount(childData.size());
            pg.setPageIndex(pageIndex);
            if (pg.getPageSize() == 0)//要求0时返回所有
            {
                pageIndex = 1;
                pageCount = childData.size();
            }
            int realPageCount = (int) Math.ceil((float) childData.size() / pageSize);
            if (pageIndex > realPageCount) {
                pageIndex = realPageCount;
                pg.setPageIndex(pageIndex + 1);
            }
            int startIndex = (pageIndex - 1) * pageSize;
            if (startIndex < 0)
                startIndex = 0;
            List childDataNews = new ArrayList(childData).subList(startIndex, pageCount);

            return new RetrieveChildResult() {
                {
                    setResult(new ArrayList<>(childDataNews));
                    setPagination(pg);
                }
            };
        }
        pagination.setTotalCount(childData.size());
        return new RetrieveChildResult() {
            {
                setResult(new ArrayList<>(childData));
                setPagination(pagination);
            }
        };
    }
}
